package com.appointment.controller;

import com.appointment.annotation.RoleRequired;
import com.appointment.dto.*;
import com.appointment.pojo.Appointment;
import com.appointment.pojo.Log;
import com.appointment.pojo.Professor;
import com.appointment.result.R;
import com.appointment.service.AppointmentService;
import com.appointment.service.LogService;
import com.appointment.service.ProfessorService;
import com.appointment.utils.Jwt.JwtRoles;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/appointment")
@Slf4j
public class AppointmentController {

    @Autowired
    private AppointmentService appointmentService;

    @Autowired
    private ProfessorService professorService;

    @Autowired
    private LogService logService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @RoleRequired(JwtRoles.USER)
    @PostMapping("/user/getList")
    private R<Object> getList(HttpServletRequest request, @Valid @RequestBody AppointmentListRequestDto appointmentListRequestDto) {
        String id = (String) request.getAttribute("id");
        // 创建分页查询
        int pageNum = appointmentListRequestDto.getPageNum();
        int pageSize = appointmentListRequestDto.getPageSize();
        Page<Appointment> appointmentPage = new Page<>(pageNum, pageSize);
        // 创建查询构造
        LambdaQueryWrapper<Appointment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Appointment::getUserId, id);
        queryWrapper.select(Appointment::getId, Appointment::getProfessorId, Appointment::getAppointmentTime, Appointment::getAppointmentContent);
        // 按照预约更新时间降序，距离现在时间越短越靠前
        queryWrapper.orderByDesc(Appointment::getUpdateTime);
        appointmentService.page(appointmentPage, queryWrapper);
        Page<SimpleAppointmentDto> appointmentDtoPage = new Page<>(pageNum, pageSize);
        BeanUtils.copyProperties(appointmentPage, appointmentDtoPage, "records");
        List<Appointment> records = appointmentPage.getRecords();
        List<SimpleAppointmentDto> simpleAppointmentDtoList = records.stream().map((appointment) -> {
            SimpleAppointmentDto simpleAppointmentDto = new SimpleAppointmentDto();
            BeanUtils.copyProperties(appointment, simpleAppointmentDto);
            // 查询professor姓名
            String professorId = appointment.getProfessorId();
            LambdaQueryWrapper<Professor> professorLambdaQueryWrapper = new LambdaQueryWrapper<>();
            professorLambdaQueryWrapper.select(Professor::getName);
            professorLambdaQueryWrapper.eq(Professor::getId, professorId);
            Professor professor = professorService.getOne(professorLambdaQueryWrapper);
            if (professor != null) {
                simpleAppointmentDto.setProfessorName(professor.getName());
            }
            // 查询日志
            String appointmentId = appointment.getId();
            LambdaQueryWrapper<Log> logLambdaQueryWrapper = new LambdaQueryWrapper<>();
            logLambdaQueryWrapper.select(Log::getAuditingStatus);
            logLambdaQueryWrapper.eq(Log::getAppointmentId, appointmentId);
            logLambdaQueryWrapper.orderByDesc(Log::getCreateTime);
            logLambdaQueryWrapper.last("limit 1");
            Log log = logService.getOne(logLambdaQueryWrapper);
            if (log != null) {
                simpleAppointmentDto.setLastAuditingStatus(log.getAuditingStatus());
            }
            return simpleAppointmentDto;
        }).collect(Collectors.toList());
        appointmentDtoPage.setRecords(simpleAppointmentDtoList);
        return R.success(appointmentDtoPage);
    }

    @RoleRequired({JwtRoles.USER, JwtRoles.PROFESSOR})
    @PostMapping("/user/getDetail")
    private R<Object> getDetail(HttpServletRequest request, @Valid @RequestBody AppointmentDetailRequestDto appointmentDetailRequestDto) {
        String id = (String) request.getAttribute("id");
        String role = (String) request.getAttribute("role");
        String appointmentId = appointmentDetailRequestDto.getId();
        LambdaQueryWrapper<Appointment> appointmentLambdaQueryWrapper = new LambdaQueryWrapper<>();
        appointmentLambdaQueryWrapper.eq(Appointment::getId, appointmentId);
        Appointment appointment = appointmentService.getOne(appointmentLambdaQueryWrapper);
        if (appointment == null) {
            return R.error("预约不存在");
        }
        if (JwtRoles.USER.equals(role) && !id.equals(appointment.getUserId())) {
            return R.error("无权查看");
        }
        if (JwtRoles.PROFESSOR.equals(role) && !id.equals(appointment.getProfessorId())) {
            return R.error("无权查看");
        }
        AppointmentDto appointmentDto = new AppointmentDto();
        BeanUtils.copyProperties(appointment, appointmentDto);
        // 查询professor姓名
        String professorId = appointment.getProfessorId();
        LambdaQueryWrapper<Professor> professorLambdaQueryWrapper = new LambdaQueryWrapper<>();
        professorLambdaQueryWrapper.select(Professor::getName);
        professorLambdaQueryWrapper.eq(Professor::getId, professorId);
        Professor professor = professorService.getOne(professorLambdaQueryWrapper);
        if (professor != null) {
            appointmentDto.setProfessorName(professor.getName());
        }
        // 查询日志
        LambdaQueryWrapper<Log> logLambdaQueryWrapper = new LambdaQueryWrapper<>();
        logLambdaQueryWrapper.select(Log::getAuditingStatus, Log::getCreateTime);
        logLambdaQueryWrapper.eq(Log::getAppointmentId, appointmentId);
        logLambdaQueryWrapper.orderByAsc(Log::getCreateTime);
        List<Log> logs = logService.list(logLambdaQueryWrapper);
        AppointmentDetailDto appointmentDetailDto = new AppointmentDetailDto();
        appointmentDetailDto.setAppointment(appointmentDto);
        appointmentDetailDto.setLogList(logs);
        return R.success(appointmentDetailDto);
    }

    @RoleRequired(JwtRoles.PROFESSOR)
    @PostMapping("/user/updateStatus")
    private R<Object> updateStatus(HttpServletRequest request, @Valid @RequestBody AppointmentUpdateStatusRequestDto appointmentUpdateStatusRequestDto) {
        String id = (String) request.getAttribute("id");
        String appointmentId = appointmentUpdateStatusRequestDto.getId();
        int status = appointmentUpdateStatusRequestDto.getStatus();
        appointmentService.updateStatus(appointmentId, id, status);
        LambdaQueryWrapper<Log> logLambdaQueryWrapper = new LambdaQueryWrapper<>();
        logLambdaQueryWrapper.eq(Log::getAppointmentId, appointmentId);
        logLambdaQueryWrapper.orderByAsc(Log::getCreateTime);
        logLambdaQueryWrapper.select(Log::getAuditingStatus, Log::getCreateTime);
        // 查询预约记录
        List<Log> LogList = logService.list(logLambdaQueryWrapper);
        AppointmentDetailDto appointmentDetailDto = new AppointmentDetailDto();
        appointmentDetailDto.setLogList(LogList);
        return R.success(appointmentDetailDto);
    }

    @RoleRequired(JwtRoles.USER)
    @PostMapping("/user/add")
    private R<Object> add(HttpServletRequest request, @Valid @RequestBody AppointmentAddRequestDto appointmentAddRequestDto) {
        String professorId = appointmentAddRequestDto.getProfessorId();
        String code = appointmentAddRequestDto.getCode();
        String phone = appointmentAddRequestDto.getUserPhone();
        String userId = (String) request.getAttribute("id");
        if (professorService.getById(professorId) == null) {
            return R.error("专家不存在");
        }
        String redisCode = redisTemplate.opsForValue().get(phone);
        if (!code.equals(redisCode)) {
            return R.error("验证码错误");
        }
        redisTemplate.delete(phone);
        Appointment appointment = new Appointment();
        BeanUtils.copyProperties(appointmentAddRequestDto, appointment);
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime localDateTime = LocalDateTime.parse(appointmentAddRequestDto.getAppointmentTime(), dateTimeFormatter);
        appointment.setAppointmentTime(Timestamp.valueOf(localDateTime));
        appointment.setUserId(userId);
        appointmentService.saveWithLog(appointment);
        Map<String, String> response = Map.of("id", appointment.getId());
        return R.success(response);
    }
}



